//
//  DownloaderTask.m
//  yuikemall
//
//  Created by yuike6 yuike6 on 12-3-1.
//  Copyright (c) 2012年 yuike. All rights reserved.
//

#import "DownloaderTask.h"
#import "header.h"

@implementation DownloaderTask

@synthesize response = response_;
@synthesize urlconnection = urlconnection_;

@synthesize recvData = recvData_;
@synthesize urlString = urlString_;

@synthesize delegate = delegate_;
@synthesize isDownloading = isDownloading_;

@synthesize isFinish;
@synthesize isCancel;

@synthesize callBackLock = callBackLock_;

- (void) dealloc
{
    [self.callBackLock lock];
    [self.callBackLock unlock];
    YRelease(response_);
    YRelease(recvData_);
    
    YRelease(urlconnection_);
    YRelease(urlString_);
    
    YRelease(callBackLock_);
    
    [super dealloc];
}

- (void) init_
{
    
    if (!self.callBackLock) {
        self.callBackLock = [[[NSLock alloc] init] autorelease];
    }
    
	self.isDownloading = NO;
    self.isFinish = NO;
	
	if (!self.urlString)
	{
		NSString *reason = [NSString stringWithFormat:@"Could not create URL from string %@", self.urlString];
		DELEGATE_CALLBACK(taskDataDownloadFailed:, reason);
		return;
	}
	
	NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:self.urlString];
	if (!theRequest)
	{
		NSString *reason = [NSString stringWithFormat:@"Could not create URL request from string %@", self.urlString];
		DELEGATE_CALLBACK(taskDataDownloadFailed:, reason);
		return;
	}
	
    
	self.urlconnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];
	if (!self.urlconnection)
	{
		NSString *reason = [NSString stringWithFormat:@"URL connection failed for string %@", self.urlString];
		DELEGATE_CALLBACK(taskDataDownloadFailed:, reason);
		return;
	}
	
	self.isDownloading = YES;	
	self.response = nil;
	
    //	[self.urlconnection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

- (void) cleanup
{
	self.recvData = nil;
	self.response = nil;
    
	self.urlconnection = nil;
	self.urlString = nil;
    
	self.isDownloading = NO;
}


- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)aResponse
{
    @autoreleasepool {
        @try 
        {
            [self.callBackLock lock];
            if (self.isCancel) {
                [self.callBackLock unlock];
                return;
            }
            // store the response information
            self.response = aResponse;
            
            [self.recvData setNeedRecvDataLenght:[self.response expectedContentLength]];
            // Check for bad connection
            if ([aResponse expectedContentLength] < 0)
            {
                NSString *reason = [NSString stringWithFormat:@"Invalid URL [%@]", self.urlString];
                DELEGATE_CALLBACK(taskDataDownloadFailed:, reason);
                [connection cancel];
                [self cleanup];
                [self stop];
                [self.callBackLock unlock];
                return;
            }
            
            if ([aResponse suggestedFilename])
            {
                DELEGATE_CALLBACK(didTaskReceiveFilename:, [aResponse suggestedFilename]);
            }
            
            [self.callBackLock unlock];
        }
        @catch (NSException *exception) {
            DebugLog(@"Error: name: %@ reason: ", exception.name, exception.reason);
        }
        @finally {
            
        }
    }    
    
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
    @autoreleasepool 
    {
        @try 
        {
            [self.callBackLock lock];
            if (self.isCancel) {
                [self.callBackLock unlock];
                return;
            }
            
            if (!theData) {
                [self.callBackLock unlock];
                return;
            }
            
            if(!self.recvData)
            {
                self.recvData = [[[DownloadRecvDataMemory alloc] init] autorelease];
            }
            
            
            [self.recvData AppendData:theData];
            if (self.response)
            {
                float expectedLength = [self.response expectedContentLength];
                float currentLength = self.recvData.length;
                float percent = currentLength / expectedLength;
                DELEGATE_CALLBACK(taskDataDownloadAtPercent:, NUMBER(percent));
            }
            [self.callBackLock unlock];
        }
        @catch (NSException *exception) {
            DebugLog(@"Error: name: %@ reason: ", exception.name, exception.reason);
        }
        @finally {
            
        } 
    }
    
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    @autoreleasepool 
    {
        @try {
            [self.callBackLock lock];
            if (self.isCancel) {
                [self.callBackLock unlock];
                return;
            }
            self.response = nil;	
            self.isFinish = YES;
            if (self.delegate && self.urlconnection)
            {		
                NSData *theData = [self.recvData data] ;
                DELEGATE_CALLBACK(didTaskReceiveDataFinish:, theData);
            }
            //	[self.urlconnection unscheduleFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
            [self cleanup];
            [self stop];
            
            self.isFinish = YES;
            [self.callBackLock unlock];
        }
        @catch (NSException *exception) {
            DebugLog(@"Error: name: %@ reason: ", exception.name, exception.reason);
        }
        @finally {
            
        }
    }    
    
}



- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    @try 
    {
        [self.callBackLock lock];
        self.isDownloading = NO;
        DebugLog(@"Error: Failed connection, %@", [error localizedDescription]);
        DELEGATE_CALLBACK(taskDataDownloadFailed:, @"Failed Connection");
        [self cleanup];    
        [self stop];
        [self.callBackLock unlock];
    }
    @catch (NSException *exception) {
        DebugLog(@"Error: name: %@ reason: ", exception.name, exception.reason);
    }
    @finally {
        
    }
    
}



- (void) cancelDownloader
{
    self.isFinish = YES;
    self.isCancel = YES;
    [self.urlconnection cancel];
    [self cleanup];
}

- (void) cancel
{
    [self cancelDownloader];
    [super cancel];
}

- (void) stop
{
    [self cancelDownloader];
    [super stop];
}

- (void) downloadUrl:(NSString *) aURLString
{
    if ([NSString isNilOrEmpty:aURLString]) {
        [self stop];
    }
    
    if(self.isDownloading)
    {
        [self stop];
    }
    
    [self download:[NSURL URLWithString:aURLString]];
    
}
- (void) download:(NSURL *) url
{
    if ([url isFileURL]) 
    {
        [self stop];
    }
    self.urlString = url;
}

- (void) main
{    
    @autoreleasepool {
        if (self.bNeedStop) {
            return;
        }
        self.isCancel = NO;
        [self init_];
        
        while (TRUE) 
        {
            if (self.bNeedStop ||
                self.isFinish ||
                self.isCancel ||
                !self.urlconnection) 
            {
                return;
            }
            
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];    
        } 
    }    
}
@end
